CSS lay-out met flexbox case study biblio - homepagina
We willen leren werken met flexbox. Om dat goed te kunnen doen bereiden we een html pagina voor met elementen die geschikt zijn voor het leren van flexbox. Als onderwerp kiezen we een winkel.
Video
Oplossing
- Wat hieraan voorafgaat
- Wireframe naar HTML
We nemen onze wireframe voor de homepagina en trekken kaders rond de elementen kiezen voor elk kader een HTML element: - HTML
Op basis van de tekening hierboven maken de we de volgende HTML:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="application-name" content="Biblio webwinkel"> <meta name="description" content="Verkoop tweedehandsboeken"> <meta name="keywords" content="boeken, books, tweedehands"> <meta name="author" content="Jef Inghelbrecht"> <meta name="date" content="2020-10-05"> <meta name="time" content="17:40:33"> <link href="css/biblio.css" rel="stylesheet" type="text/css" /> <title>Biblio tweedehandsboeken</title> </head> <body> <header class="control-panel"> <a class="logo" href="index.html"></a> <nav class="horizontal-nav"> <a href="index.html">Home</a> <a href="#">Boeken</span></a> <a href="#">Bestelformulier</span></a> </nav> </header> <div class="content"> <aside>Ruime keuze uit: <ul> <li>filosofie</li> <li>geschiedenis</li> <li>anthropologie</li> <li>wiskunde</li> </ul> </aside> <main> <section>Uitleg over de site</section> <section> <article>Cover 1</article> <article>Cover 2</article> <article>Cover 3</article> </section> </main> </div> <footer>© Jef Inghelbrecht</footer> </body> </html>
We hebben de navigatie structuur en klassenamen overgenomen uit een vorige les, CSS Horizontale navigatie opmaak.
-
CSS
- We nemen de CSS uit de les over horizontale navigatie over, maar we veranderen wel de afbeelding van het logo:
.logo { display: block; height: 100%; width: 15%; background-image: url(../image/logobookshelf.png); background-size: contain; background-repeat: no-repeat; float: left; } .horizontal-nav { width: 85%; height: 100%; padding: 1rem 0 0 0; } .horizontal-nav a { margin-left: 4rem; text-decoration: none; cursor: pointer; color: #E20513; /* AP rood */ font-size: 1.4rem; position: relative; } .horizontal-nav a::after { position: absolute; top: 0; left: 0; content: ''; border-bottom: #AD0F09 solid 3px; /* AP donker rood */ width: 0; background: transparent; transition: width .2s ease, border-bottom .3s ease; text-align: center; height: 2rem; } .horizontal-nav a:hover::after { width: 100%; }
- Met universele selector stellen we voor alle elementen de volgende waarden in:
* { box-sizing: border-box; margin: 0; padding: 0; }
-
Vermits we in percenten gaan meten, stellen we de hoogte en breedte van het html element in. We willen dat de homepagina de volledige hoogte en breedte van de viewport inneemt:
html { height: 100%; width: 100% }
-
Het
header
, div enfooter
element inbody
gaan we met flexbox lay-outen. Het zijn drie elementen die onder elkaar moeten staan. Verder moet hetbody
element de volledige viewport innemen en stellen we het lettertype in voor de pagina:body { height: 100%; width: 100%; display: flex; flex-direction: column; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
- Het header element moet minimum 2em hoog zijn en verder moet het kunnen een klien beetje groeien of krimpen indien noodzakelijk is:
body>header { flex-grow: .1; flex-shrink: .1; flex-basis: 2em; }
- Het
div
element waarin de content komt te staan is ingewikkelder. Hetaside
element en hetmain
element moeten op 1 flexlijn als het scherm breed genoeg is, anders moeten die onder elkaar geplaatst worden. Hier gaan we een media-query gebruiken. We volgen het principe van mobile first en stellen een stijlregel op die ervan uitgaat dat de website op een mobiel toestel geraadpleegd wordt.We stellenflex-grow
enflex-shrink
in omdat dit element alle ruimte moet innemen tussen hetheader
en hetfooter
element:/** * Let's do a column distribution * (mobile first) * flex value is 1 1 auto to make * body skrinkable and extensible */ body>div { display: flex; flex-grow: 1; flex-shrink: 1; flex-basis: auto; flex-direction: column; }
Als de viewport breder wordt schakelen we over naar flex-direction: row:@media (min-width: 600px) { /** * Body>div items are now side by side */ body>div { flex-direction: row; } }
- In het
main
element moeten de sections altijd onder elkaar komen te staan, onafhankelijk van de breedte van de viewport. Dus moet hetmain
element een flex-container worden. Daarnaast moet hetmain
element kunnen groeien en krimpen./** * Content body item is made * extensible too. */ body>div>main { flex-grow: 1; flex-shrink: 1; flex-basis: auto; display: flex; flex-direction: column; }
- Het section element zelf moet kunnen groeien en krimpen en we tekenen er een zwart kader rond. Dit doen we om flexbox beter aan het werk te kunnen zien:
/** * sections in main are made * extensible too. */ body>div>main>section { flex-grow: 1; flex-shrink: 1; flex-basis: auto; border: solid black 2px; }
- In het onderste section element komen de covers van de boeken te staan. We maken van dat element dus ook een flex-container. Mobile first wil zeggen dat we de covers plaatsen op een verticale flexlijn:
/** * Let's do a column distribution * (mobile first) */ body>div>main>section:nth-child(2) { display: flex; flex-direction: column; }
Als de viewport breder wordt, plaatsen we de artikels op een horizontale flexlijn:
@media (min-width: 600px) { body>div>main>section:nth-child(2) { flex-direction: row; } }
- De
article
elementen in de tweede sectie, waarin de covers komen te staan, moeten kunnen groeien en krimpen en we trekken er een zwart kader rond:body>div>main>section:nth-child(2)>article { flex-grow: 1; flex-shrink: 1; flex-basis: auto; border: solid black 1px; }
- Rond het aside element tekenen we een zwart kader:
body>div>aside { border: solid black 2px; }
Als de viewport breder wordt krijgt hetaside
element een vaste breedte en kan die niet meer groeien of krimpen:@media (min-width: 600px) { /** * Sidebars have a basic 260 width * and are not really flexible anymore */ body>div>aside { flex-grow: 0; flex-shrink: 0; flex-basis: 260px; } }
- Resultaat
- De volledige CSS uit css/biblio.css:
* { box-sizing: border-box; margin: 0; padding: 0; } /** * Make body at least 100% height * You can use a combination * of height: 100% in <html> and * height: 100% in <body>. */ html { height: 100%; width: 100% } body { height: 100%; width: 100%; display: flex; flex-direction: column; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body>header { flex-grow: .1; flex-shrink: .1; flex-basis: 2em; } /** * Let's do a column distribution * (mobile first) * flex value is 1 1 auto to make * body skrinkable and extensible */ body>div { display: flex; flex-grow: 1; flex-shrink: 1; flex-basis: auto; flex-direction: column; } /** * Content body item is made * extensible too. */ body>div>main { flex-grow: 1; flex-shrink: 1; flex-basis: auto; display: flex; flex-direction: column; } /** * sections in main are made * extensible too. */ body>div>main>section { flex-grow: 1; flex-shrink: 1; flex-basis: auto; border: solid black 2px; } /** * Let's do a column distribution * (mobile first) */ body>div>main>section:nth-child(2) { display: flex; flex-direction: column; } body>div>main>section:nth-child(2)>article { flex-grow: 1; flex-shrink: 1; flex-basis: auto; border: solid black 1px; } body>div>aside { border: solid black 2px; } /** * Let's introduce bigger screen */ @media (min-width: 600px) { /** * Body items are now side by side */ body>div { flex-direction: row; } /** * Sidebars have a basic 260 width * and are not really flexible anymore */ body>div>aside { flex-grow: 0; flex-shrink: 0; flex-basis: 260px; } body>div>main>section:nth-child(2) { flex-direction: row; } } .logo { display: block; height: 100%; width: 15%; background-image: url(../image/logobookshelf.png); background-size: contain; background-repeat: no-repeat; float: left; } .horizontal-nav { width: 85%; height: 100%; padding: 1rem 0 0 0; } .horizontal-nav a { margin-left: 4rem; text-decoration: none; cursor: pointer; color: #E20513; /* AP rood */ font-size: 1.4rem; position: relative; } .horizontal-nav a::after { position: absolute; top: 0; left: 0; content: ''; border-bottom: #AD0F09 solid 3px; /* AP donker rood */ width: 0; background: transparent; transition: width .2s ease, border-bottom .3s ease; text-align: center; height: 2rem; } .horizontal-nav a:hover::after { width: 100%; }
- We nemen de CSS uit de les over horizontale navigatie over, maar we veranderen wel de afbeelding van het logo: